package com.micro.ai.files.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.micro.ai.commons.exception.BusinessException;
import com.micro.ai.files.entity.FileUploadRecord;
import com.micro.ai.files.mapper.FileUploadRecordMapper;
import com.micro.ai.files.service.FileUploadRecordService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;

/**
 * 文件上传记录服务实现
 * 
 * @author micro-ai
 * @since 0.0.1
 */
@Slf4j
@Service
public class FileUploadRecordServiceImpl extends ServiceImpl<FileUploadRecordMapper, FileUploadRecord> implements FileUploadRecordService {

    @Override
    @Transactional(rollbackFor = Exception.class)
    public FileUploadRecord create(FileUploadRecord record) {
        if (record == null) {
            throw new BusinessException("F0000", "上传记录信息不能为空");
        }
        
        if (!StringUtils.hasText(record.getTenantId())) {
            throw new BusinessException("F0000", "租户ID不能为空");
        }
        
        if (!StringUtils.hasText(record.getUploadId())) {
            throw new BusinessException("F0000", "上传ID不能为空");
        }
        
        // 检查上传ID是否已存在
        FileUploadRecord existing = getByUploadId(record.getUploadId());
        if (existing != null) {
            throw new BusinessException("F0001", "上传ID已存在: " + record.getUploadId());
        }
        
        LocalDateTime now = LocalDateTime.now();
        record.setCreatedAt(now);
        record.setUpdatedAt(now);
        
        if (record.getStatus() == null) {
            record.setStatus("uploading");
        }
        if (record.getUploadedChunks() == null) {
            record.setUploadedChunks(0);
        }
        if (record.getTotalChunks() == null || record.getTotalChunks() < 1) {
            throw new BusinessException("F0000", "总分片数必须大于0");
        }
        
        boolean success = this.save(record);
        if (!success) {
            throw new BusinessException("F0003", "保存上传记录失败");
        }
        
        log.info("创建上传记录成功: recordId={}, uploadId={}, filename={}", 
                record.getId(), record.getUploadId(), record.getFilename());
        return record;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public FileUploadRecord update(String id, FileUploadRecord record) {
        if (!StringUtils.hasText(id)) {
            throw new BusinessException("F0000", "记录ID不能为空");
        }
        if (record == null) {
            throw new BusinessException("F0000", "上传记录信息不能为空");
        }
        
        FileUploadRecord existing = this.getById(id);
        if (existing == null) {
            throw new BusinessException("F0002", "上传记录不存在: " + id);
        }
        
        record.setId(id);
        record.setUpdatedAt(LocalDateTime.now());
        
        boolean success = this.updateById(record);
        if (!success) {
            throw new BusinessException("F0003", "更新上传记录失败");
        }
        
        log.info("更新上传记录成功: recordId={}, uploadId={}", id, existing.getUploadId());
        return record;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(String id) {
        if (!StringUtils.hasText(id)) {
            throw new BusinessException("F0000", "记录ID不能为空");
        }
        
        FileUploadRecord record = this.getById(id);
        if (record == null) {
            throw new BusinessException("F0002", "上传记录不存在: " + id);
        }
        
        boolean success = this.removeById(id);
        if (!success) {
            throw new BusinessException("F0003", "删除上传记录失败");
        }
        
        log.info("删除上传记录成功: recordId={}, uploadId={}", id, record.getUploadId());
    }

    @Override
    public FileUploadRecord getByUploadId(String uploadId) {
        if (!StringUtils.hasText(uploadId)) {
            return null;
        }
        
        LambdaQueryWrapper<FileUploadRecord> query = new LambdaQueryWrapper<>();
        query.eq(FileUploadRecord::getUploadId, uploadId);
        
        return this.getOne(query);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateProgress(String uploadId, int uploadedChunks) {
        FileUploadRecord record = getByUploadId(uploadId);
        if (record == null) {
            throw new BusinessException("F0002", "上传记录不存在: " + uploadId);
        }
        
        if (!"uploading".equals(record.getStatus())) {
            throw new BusinessException("F0000", "上传记录状态不正确，无法更新进度");
        }
        
        record.setUploadedChunks(uploadedChunks);
        record.setUpdatedAt(LocalDateTime.now());
        
        // 检查是否所有分片都已上传
        if (uploadedChunks >= record.getTotalChunks()) {
            record.setStatus("completed");
        }
        
        boolean success = this.updateById(record);
        if (!success) {
            throw new BusinessException("F0003", "更新上传进度失败");
        }
        
        log.debug("更新上传进度: uploadId={}, uploadedChunks={}/{}", uploadId, uploadedChunks, record.getTotalChunks());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void completeUpload(String uploadId) {
        FileUploadRecord record = getByUploadId(uploadId);
        if (record == null) {
            throw new BusinessException("F0002", "上传记录不存在: " + uploadId);
        }
        
        record.setStatus("completed");
        record.setUploadedChunks(record.getTotalChunks());
        record.setUpdatedAt(LocalDateTime.now());
        
        boolean success = this.updateById(record);
        if (!success) {
            throw new BusinessException("F0003", "完成上传失败");
        }
        
        log.info("完成上传: uploadId={}, filename={}", uploadId, record.getFilename());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelUpload(String uploadId) {
        FileUploadRecord record = getByUploadId(uploadId);
        if (record == null) {
            throw new BusinessException("F0002", "上传记录不存在: " + uploadId);
        }
        
        if ("completed".equals(record.getStatus())) {
            throw new BusinessException("F0000", "上传已完成，无法取消");
        }
        
        record.setStatus("cancelled");
        record.setUpdatedAt(LocalDateTime.now());
        
        boolean success = this.updateById(record);
        if (!success) {
            throw new BusinessException("F0003", "取消上传失败");
        }
        
        log.info("取消上传: uploadId={}, filename={}", uploadId, record.getFilename());
    }

    @Override
    public Page<FileUploadRecord> pageQuery(int pageNum, int pageSize, String tenantId, 
                                            String keyword, String status) {
        if (pageNum < 1) {
            pageNum = 1;
        }
        if (pageSize < 1 || pageSize > 100) {
            pageSize = 20;
        }
        
        Page<FileUploadRecord> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<FileUploadRecord> query = new LambdaQueryWrapper<>();
        
        if (StringUtils.hasText(tenantId)) {
            query.eq(FileUploadRecord::getTenantId, tenantId);
        }
        if (StringUtils.hasText(status)) {
            query.eq(FileUploadRecord::getStatus, status);
        }
        if (StringUtils.hasText(keyword)) {
            query.and(q -> q.like(FileUploadRecord::getFilename, keyword)
                          .or().like(FileUploadRecord::getUploadId, keyword));
        }
        
        query.orderByDesc(FileUploadRecord::getCreatedAt);
        
        return this.page(page, query);
    }
}

